﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Semantics;

using GraphBase.UI;
namespace GraphBase.Presentation
{
    /// <summary>
    /// 所属在GraphBaseUserControl下，用于节点及边的图显示
    /// </summary>
    public partial class GraphGraphUserControl : GraphControlBase
    {
        public int HopDistance = 3;
        public ISuperGraph SuperGraph
        {
            get
            {
                if (this.Graph is Semantics.SubGraph)
                    return ((Semantics.SubGraph)this.Graph).SuperGraph;
                else if (!(Graph is ISuperGraph))
                    throw new Exception("The graph of this GraphGraphControl is not a SuperGraph");
                return (ISuperGraph)this.Graph;
            }
        }

        //调用父级的值
        //public GraphbaseUserControl gbuc;
        //与VisualGraph的传值
        Extension.VisualGraph _visualgraph;
        Extension.VisualGraph VisualGraph{
            get{
                if (_visualgraph==null)
                {
                    _visualgraph=new Extension.VisualGraph(this.Graph);//, GraphDatabase.SqliteBase);
                }
                return _visualgraph;
            }
        }
        //与GraphPositionManager的传值
        GraphPositionManager _gmgr;
        public GraphPositionManager GraphPositionManager
        {
            get
            {
                if (this.DesignMode)
                    return null;
                if (this.Graph == null)
                    return null;
                if (_gmgr == null)
                {
                    _gmgr = new GraphPositionManager(this.Graph, this.VisualGraph,this,this.Size);
                }
                return _gmgr;
            }
        }
        public bool ShowSubGraphElement { get; set; }       
        
        public Node GraphbaseViewType;
        public GraphView GraphView;
        public GraphPositionView PositionView;
        List<Edge> _edges;
        public List<Edge> LineEdges
        {
            get
            {
                if (this.DesignMode)
                    return null;
                if (_edges == null)
                {
                    if (PositionView == null)
                    {
                        if (GraphPositionManager.EdgeLines != null)
                        {
                            foreach (EdgePos ep in GraphPositionManager.EdgeLines.Values)
                                _edges.Add(ep.pedge);
                            return _edges;
                        }
                        return null;
                    }
                    else
                        return PositionView.ViewEdges();
                }
                else
                    return _edges;
            }
            set
            {
                _edges = value;
            }
        }
        List<Node> _nodes;
        public List<Node> AllNodes
        {
            get
            {
                if (this.DesignMode)
                    return null;
                if (_nodes == null)
                {
                    if (PositionView == null)
                    {
                        if (GraphPositionManager.NodePositions != null)
                        {
                            foreach (NodePos np in GraphPositionManager.NodePositions.Values)
                                _nodes.Add(np.pNode);
                            return _nodes;
                        }
                        return null;
                    }
                    else
                        return PositionView.ViewNodes();
                }
                else
                    return _nodes;
            }
            set { _nodes = value; }
        }

        #region"选中的元素"
        Node _selectednode;
        public Node SelectedNode
        {
            get
            {
                return _selectednode;
            }
            set
            {
                _selectednode = value;
                if (DesignMode)
                    return;
                if (value == null)
                {
                    return;
                    this.SelectedNodePos = null;
                }
                else
                {
                    NodePos nodepos;
                    if (this.GraphPositionManager.NodePositions.TryGetValue(_selectednode.Id, out nodepos))
                        this.SelectedNodePos = nodepos;
                }
            }
        }
        //选中的节点
        NodePos _selnode;
        NodePos SelectedNodePos
        {
            get {
                //if (this.gbuc.selNodePos != null)
                //{
                //    _selnode = this.gbuc.selNodePos;
                //}
                return _selnode; }
            set {
                this._selnode = value;
                this.GraphPositionManager.SelectedNodePos = value;
                //this.NodePropertiesControl.SelectedNodePos = value;
                //this.gbuc.SelectedNodePos = value;
                if (value != null)
                {
                    if (this.SearchManner == SearchEngine.EnumSearchManner.ByNeightbor)
                        this.GraphPositionManager.Search(this.HopDistance, _selnode);
                    if(this.SelectedNodeChangedEvent!=null)
                        this.SelectedNodeChangedEvent(this, value);
                }  
            }
        }
        public delegate void SelectedNodeChangedEventHandler(GraphGraphUserControl sender, NodePos selectednode);
        public event SelectedNodeChangedEventHandler SelectedNodeChangedEvent;
        public NodePos GetSelectedNode() { return this._selnode; }

        //选中多个节点
        List<NodePos> _selmultinodes=new List<NodePos>();
        public List<NodePos> GetSelectedMultipleNodes()
        {
            return _selmultinodes;
        }

        //选中的直线边
        public delegate void SelectedEdgeChangedEventHandler(GraphGraphUserControl sender, EdgePos selectedline);
        public event SelectedEdgeChangedEventHandler SelectedEdgeChangedEvent;
        EdgePos _sellineedge;
        EdgePos SelectedLineEdge
        {
            get { return _sellineedge; }
            set
            {
                this._sellineedge = value;
                this.GraphPositionManager.SelectedLineEdge = value;
                if (SelectedEdgeChangedEvent != null)
                {
                    this.SelectedEdgeChangedEvent(this, value);
                }
            }
        }
        public EdgePos GetSelectedLine() { return this._sellineedge; }
        //选中的圆弧边
        EdgePos _selarcedge;
        EdgePos SelectedArcEdge
        {
            get { return _selarcedge; }
            set
            {
                this._selarcedge = value;
                this.GraphPositionManager.SelectedArcEdge=value;
            }
        }
        public EdgePos GetSelectedArc() { return this._selarcedge; }
        #endregion

        #region"枚举"
        enum EnumWorkState//选中状态枚举
        {
            NoSelection,//无选中
            SelectedOne,//已选中一项
            SelectedMultiple,//选中多项
            Editing,//正在编辑
        }
        enum EnumWorkManner//选中后的动作
        {
            Nothing,
            SinglePoint,
            MultiplePoint,
            Moving,
        }
        EnumWorkState WorkState = EnumWorkState.NoSelection;
        EnumWorkManner WorkManner = EnumWorkManner.Nothing;
        public SearchEngine.EnumSearchManner SearchManner;
        #endregion
        public event GraphControlBase.NodeEventHandler NodeDeletedEvent;
        public event GraphControlBase.MultipleNodesEventHandler MultipleNodesDeletedEvent;
        public event GraphControlBase.EdgeEventHandler EdgeDeletedEvent;
        public event GraphControlBase.EdgeEventHandler EdgeCreatedEvent;
        public event GraphControlBase.EdgeEventHandler EdgeEditedEvent;
        public event GraphControlBase.NodeEventHandler NodeOpenEvent;

        public delegate void SizeChangedEventHandler(GraphGraphUserControl sender, EventArgs e);
        public event GraphGraphUserControl .SizeChangedEventHandler SizeChangedEvent;
               

        public GraphGraphUserControl()
        {
            InitializeComponent();
            this.DoubleBuffered = true;//加了界面不抖
            this.SelNodeTextBox.Visible = false;//默认不可见
            this.SelNodeTextBox.Font = new Font(FontFamily.GenericSansSerif, 10.0f);
            this.SelNodeTextBox.TextChanged += new EventHandler(SelNodeTextBox_TextChanged);//文本框文本改变
            this.SelNodeTextBox.KeyDown += new KeyEventHandler(SelNodeTextBox_KeyDown);//按键
            this.Controls.Add(this.SelNodeTextBox);

            this.NewNodeTextBox.Visible = false;
            this.NewNodeTextBox.KeyDown += new KeyEventHandler(NewNodeTextBox_KeyDown);
            this.NewNodeTextBox.TextChanged+=new EventHandler(NewNodeTextBox_TextChanged);
            this.SizeChanged += new EventHandler(GraphGraphUserControl_SizeChanged);
            
            this.Controls.Add(this.NewNodeTextBox);
        }
        /// <summary>
        /// GraphGraphUserControl控件大小发生改变时应处理的事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void GraphGraphUserControl_SizeChanged(object sender, EventArgs e)
        {
            if(this.GraphPositionManager !=null )
            this.GraphPositionManager.DisplayArea = this.Size;
            
        }
        private void GraphGraphUserControl_Load(object sender, EventArgs e)
        {
        }
        private void GraphGraphUserControl_Paint(object sender, PaintEventArgs e)
        {
            Graphics g = e.Graphics;//声明Graphics对象
            if (DesignMode)
            {
                g.DrawString("GraphGraphUserControl", new Font(FontFamily.GenericSansSerif, 10.0f), new SolidBrush(Color.DarkBlue), 10, 10);
                return;
            }
            if(this.Graph == null)
            {
                g.DrawString("Node GraphBase is loaded", new Font(FontFamily.GenericSansSerif, 10.0f), new SolidBrush(Color.DarkBlue), 10, 10);
                return;
            }
            try
            {
                if (GraphPositionManager.NodePositions.Count == 0)
                    return;
                if (this.PositionView != null)
                {
                    this.PositionView.DrawGraphView(g, SearchManner);
                }
                else
                {
                    this.GraphPositionManager.DrawGraphView(g, SearchManner);
                }
                if (this.NewNodePos!= null)
                    this.GraphPositionManager.DrawNode(e.Graphics, this.NewNodePos);
            }
            catch (Exception exp)
            {
                g.DrawString(exp.ToString(), new Font(FontFamily.GenericSansSerif, 10.0f), new SolidBrush(Color.DarkBlue), 10, 10);
            }
        }
        
        public void PrepareDrawingGraph(IList<Node> nodes, IList<Edge> edges)
        {
            List<Node> newNodes = new List<Node> { };
            List<Edge> newEdges = new List<Edge> { };
            foreach (Node node in nodes)
                newNodes.Add(node);
            foreach (Edge edge in edges)
                newEdges.Add(edge);
            if (!this.ShowSubGraphElement)//不显示子图节点
            {
                foreach (Node node in nodes)
                {
                    if (node is IGraph)
                    {
                        IList<Node> inode = ((IGraph)node).GetAllNodes();
                        IList<Edge> iedges = ((IGraph)node).GetAllEdges();
                        foreach (Node subnode in inode)
                        {
                            newNodes.Remove(subnode);
                        }
                        foreach (Edge subEge in iedges)
                            newEdges.Remove(subEge);
                    }
                }
            }
            this.GraphPositionManager.PrepareDrawingNodesGraph(newNodes);
            //准备边
            this.GraphPositionManager.PrepareLineEdges(newEdges);
            //this.GraphPositionManager.PrepareArcEdges();
          
        }
       
        public void PrepareLineAndArcGraph()
        {
            //准备边
            this.GraphPositionManager.PrepareLineEdges(LineEdges);
            this.GraphPositionManager.PrepareArcEdges();
        }

        /*
        /// <summary>
        /// 将Node类型转换成NodePos类型
        /// </summary>
        /// <param name="node">Node类型的节点</param>
        /// <returns></returns>
        public NodePos NodeConvertToPos(Node node)
        {
            NodePos NP = null;
            if(GraphPositionManager.NodePositions.Count>0)
            {
                foreach (NodePos np in GraphPositionManager.NodePositions.Values)
                {
                    if (np.pNode.Id == node.Id)
                    {
                        NP = np;
                        break;
                    }
                }
            }
            return NP;
        }
        */
        #region"编辑控件"
        bool InProgram = false;
        TextBox SelNodeTextBox = new TextBox();
        TextBox NewNodeTextBox = new TextBox();
        bool KeyEnter = false;
        void BeginEdit(Point location)
        {
            this.SelNodeTextBox.Location = location;
            this.SelNodeTextBox.Visible = true;
            this.InProgram = true;
            this.SelNodeTextBox.Text = this.SelectedNodePos.pNode.Label;
            this.InProgram = false;
        }
    
        void SelNodeTextBox_KeyDown(object sender, KeyEventArgs e)
        {
            if (InProgram)//程序改变非互动操作改变
                return;
            if (e.KeyCode == Keys.Enter)
            {
                KeyEnter = true;
                try
                {
                    this.SelNodeTextBox_TextChanged(null, null);
                    this.SelNodeTextBox.Visible = false;
                }
                catch (Exception exp)
                {
                    MessageBox.Show(exp.ToString());
                }
            }
        }

        public delegate void NodeLabelChangedEventHandler(Node changednode);
        public event NodeLabelChangedEventHandler NodeLabelChangedEvent;
        void SelNodeTextBox_TextChanged(object sender, EventArgs e)
        {
            if (InProgram)//程序改变非互动操作改变
                return;
            try
            {
                //修改数据库记录
                if (IsSecondlySelected)
                {
                    if (KeyEnter == true)
                    {
                        base.Graph.UpdateNode(SelectedNodePos.pNode, SelNodeTextBox.Text.Trim());
                        foreach (NodePos np in GraphPositionManager.NodePositions.Values)
                        {
                            if (np.cPoint == SelectedNodePos.cPoint)
                            {
                                np.pNode.Label = SelNodeTextBox.Text.Trim();
                                break;
                            }
                        }
                        //this.gbuc.Refresh();
                        this.Refresh();
                        if(this.NodeLabelChangedEvent!=null)
                            this.NodeLabelChangedEvent(SelectedNodePos.pNode);
                    }
                }
            }
            catch (Exception exp)
            {
                MessageBox.Show(exp.ToString());
            }

        }

        void NewNodeTextBox_KeyDown(object sender, KeyEventArgs e)
        {
            if (InProgram)//程序改变非互动操作改变
                return;
            if (e.KeyCode == Keys.Return)
            {
                KeyEnter = true;
                this.NewNodeTextBox.Text = this.NewNodeTextBox.Text.Trim();
                if (this.NewNodeTextBox.Text.Length == null)
                {
                    MessageBox.Show(this, "节点标记不能为空!");
                    return;
                }
                try
                {
                    this.EditCurrentNode();//(null, null);
                    if (this.Graph is GraphDatabase)
                        ((GraphDatabase)this.Graph).SaveNodePosision(NewNodePos.pNode, NewNodePos.cPoint);
                    else
                        this.Graph.SetNodeAttribute(NewNodePos.pNode, Node.AttributesNames.Location, NewNodePos.cPoint);
                    this.NewNodeTextBox.Visible = false;
                    NewNodePos = null;
                }
                catch (Exception exp)
                {
                    MessageBox.Show(exp.ToString());
                }
            }
        }
        void NewNodeTextBox_TextChanged(object sender, EventArgs e)
        {
            if (InProgram)//程序改变非互动操作改变
                return;
            try
            {
                if (canediting)
                {
                    if (KeyEnter == true)
                    {
                    }
                }
            }
            catch (Exception exp)
            {
                MessageBox.Show(exp.ToString());
            }
        }

        void EditCurrentNode()
        {
            string label = NewNodeTextBox.Text.Trim();
            base.Graph.UpdateNode(NewNodePos.pNode, label);
            NewNodePos.pNode.Label = label;
            NewNodePos.label = label;
            //foreach (NodePos np in GraphPositionManager.NodePositions.Values)
            //{
            //    if (np.cPoint == NewNodePos.cPoint)
            //    {
            //        np.pNode.Label = NewNodeTextBox.Text.Trim();
            //        break;
            //    }
            //}
            NewNodePos.label = NewNodePos.pNode.Label;
            this.Refresh();
        }
        #endregion

        #region"节点与边的选中、移动--鼠标事件"

        bool IsSecondlySelected = false;//是否是第二次选中
        PointF Local=new PointF();//当前位置
        Point prePoint = new Point();//初始点
        Point tempPoint = new Point();//临时位置
        int dx = 0;//选中节点与临时节点x轴的距离
        int dy = 0;//选中节点与临时节点y轴的距离
        Point PopupMenuPoint;//鼠标右击的位置
        bool canediting = false;//是否编辑
        NodePos tempnode = null;//存放的临时选中节点
        //选中的节点
        NodePos GetSelectedNodePos(MouseEventArgs e)
        {
            foreach (NodePos npos in GraphPositionManager.NodePositions.Values)
            {
                int x4 = npos.cPoint.X;//选中节点左上角那个坐标
                int y4 = npos.cPoint.Y;
                if ((e.X <= (x4 + 35)) && (e.X >= x4) && (e.Y <= y4 + 35) && (e.Y >= y4))
                {
                    return npos;
                }
                //break;
            }
            return null;
        }        
        //选中的直线边
        EdgePos GetSelectedLineEdgePt(MouseEventArgs e)
        {
            Local.X=e.X;
            Local.Y=e.Y;
            foreach (EdgePos edgept in GraphPositionManager.EdgeLines.Values)
            {
                if (Geometry.IsPointInLine(edgept.startPoint, edgept.endPoint, this.Local))//判断是否在线段上
                {
                    return edgept;
                }
            }
            return null;
        }
        //选中的圆弧边
        EdgePos GetSelectedArcEdgePt(MouseEventArgs e)
        {
            foreach (EdgePos edgept in GraphPositionManager.EdgePoints.Values)
            {
                if (Geometry.IsPointInArc(edgept.startPoint, edgept.endPoint, this.Local,edgept.PointArc_O,edgept.Arc_d))//判断是否在弧上
                {
                    return edgept;
                }
            }
            return null;
        }
        private void GraphGraphUserControl_MouseDown(object sender, MouseEventArgs e)
        {
            //Graphics g = this.CreateGraphics();
            //List<NodePos> selectednodes = null;
            if (this.Graph== null && this.Graph == null)
                return;
            try
            {
                NodePos selectednode = this.GetSelectedNodePos(e);//确定选中的节点
                EdgePos selectedlineedge = this.GetSelectedLineEdgePt(e);//确定选中的直线边
                EdgePos selectedarcedge = this.GetSelectedArcEdgePt(e);//确定选中的圆弧边
                Point p1 = new Point(e.X, e.Y);
                prePoint = p1;//初始点
                this.tempPoint = prePoint;
                if ((Control.ModifierKeys == Keys.Control))//按下CTRL键
                {
                    if (selectednode != SelectedNodePos) //若选中的节点不是被选节点
                    {
                        if (this.SelectedNodePos != null && tempnode == SelectedNodePos)//若被选节点（第一个选中节点）不为空,选中的第二个节点与存放在临时节点中的节点值相同
                        {
                            this._selmultinodes.Remove(SelectedNodePos);
                        }
                        if (this.SelectedNodePos != null && selectednode != null)//若第一个选中节点不为空，并且第二个选中节点也不为空
                        {
                            this._selmultinodes.Add(this.SelectedNodePos);
                            tempnode = selectednode;
                        }
                        SelectedNodePos = selectednode;
                        this._selmultinodes.Add(SelectedNodePos);
                        this.WorkState = EnumWorkState.SelectedMultiple;
                    }
                }
                else if (e.Button == System.Windows.Forms.MouseButtons.Left)
                {
                    this._selmultinodes.Clear();
                    if (selectednode != SelectedNodePos)//第一次点击节点
                    {
                        //this.GraphPositionManager.DrawSelectedRectangle(g, e, selectednode);
                        this.WorkState = EnumWorkState.SelectedOne;
                        this.WorkManner = EnumWorkManner.SinglePoint;
                        IsSecondlySelected = false;
                        //tempNodePos = selectednode;
                        //SelectedNodePos = tempNodePos;
                        SelectedNodePos = selectednode;
                    }
                    else if (SelectedNodePos == selectednode && SelectedNodePos != null)//第二次点击节点
                    {
                        if (SelectedNodePos.IsInRectangle(e))
                        {
                            this.WorkState = EnumWorkState.Editing;
                            this.WorkManner = EnumWorkManner.SinglePoint;
                            IsSecondlySelected = true;//可以进入编辑状态
                        }
                        //tempNodePos=null;
                    }
                    
                }
                else if (e.Button == System.Windows.Forms.MouseButtons.Right)
                {
                    this.SelectedNodePos = this.GetSelectedNodePos(e);//确定选中的节点
                }
                if (SelectedNodePos == null)
                {
                    this.SearchManner = SearchEngine.EnumSearchManner.All;
                    this.WorkState = EnumWorkState.NoSelection;
                    this.WorkManner = EnumWorkManner.Nothing;
                }
                else
                {
                    dx = Math.Abs(SelectedNodePos.cPoint.X - tempPoint.X);
                    dy = Math.Abs(SelectedNodePos.cPoint.Y - tempPoint.Y);
                    this.SearchManner = SearchEngine.EnumSearchManner.ByNeightbor;
                }
                if(SelectedLineEdge != selectedlineedge)
                    SelectedLineEdge = selectedlineedge;
                if(SelectedArcEdge != selectedarcedge)
                    SelectedArcEdge = selectedarcedge;
                
            }
            catch (Exception exp)
            {
                MessageBox.Show(exp.ToString());
            }
            this.Refresh();
        }
        public List<Edge> edgeNeighbors;
        private void GraphGraphUserControl_MouseMove(object sender, MouseEventArgs e)
        {
            Point p2 = new Point(e.X, e.Y);
            int distance = Math.Abs(e.X - prePoint.X) + Math.Abs(e.Y - prePoint.Y);
            if (distance < 4)
            { return; }
            if (this.SelectedNodePos == null)
                return;
            if (e.Button != MouseButtons.Left)
                return;
            try
            {
                this.WorkManner = EnumWorkManner.Moving;
                SelectedNodePos.cPoint.X = e.X-dx;//确定选中节点的位置
                SelectedNodePos.cPoint.Y = e.Y-dy;
                if(PositionView!=null)
                    this.PositionView.LoadGraphView(GraphView);
                if (SearchManner == SearchEngine.EnumSearchManner.ByNeightbor)
                {
                    IList<Edge> connectededges = this.Graph.GetEdges(this.SelectedNodePos.pNode);
                    if (PositionView == null)//无PositionView情形
                        this.GraphPositionManager.UpdateLineEdges(connectededges);
                    //else
                    //    PositionView
                    //this.GraphPositionManager.PrepareNeighborEdges();
                    //this.PrepareNeighborDrawing();
                }
                else
                {
                    if (PositionView == null)
                        this.PrepareLineAndArcGraph();
                }
                this.Refresh();
            }
            catch (Exception exp)
            {
                MessageBox.Show(exp.ToString());
            }
        }
        private void GraphGraphUserControl_MouseUp(object sender, MouseEventArgs e)
        {
            Graphics g = this.CreateGraphics();
            try
            {
                if (e.Button == System.Windows.Forms.MouseButtons.Right)
                {
                    PopupMenuPoint = e.Location;
                    canediting = true;
                    return;
                }
                if (Control.ModifierKeys == Keys.Control)//按下CTRL键
                {
                    return;
                }
                switch (this.WorkManner)
                {
                    case EnumWorkManner.Moving:
                        {
                            SelectedNodePos.cPoint.X = e.X - dx;//确定选中节点的位置
                            SelectedNodePos.cPoint.Y = e.Y - dy;
                            this.Graph.SetNodeAttribute(SelectedNodePos.pNode, Node.AttributesNames.Location, SelectedNodePos.cPoint);
                            this.WorkManner = EnumWorkManner.Nothing;
                            break;
                        }
                    case EnumWorkManner.SinglePoint:
                    case EnumWorkManner.Nothing:
                    default:
                        if (this.canediting == false)
                        {
                            this.NewNodeTextBox.Visible = false;
                        }
                        if (this.SelectedNodePos == null)
                        {
                            this.SelNodeTextBox.Visible = false;
                        }
                        else
                        {
                            if (this.IsSecondlySelected)
                            {
                                //Point point = new Point(SelectedNodePos.selectedRectangle_X, SelectedNodePos.selectedRectangle_Y);
                                BeginEdit(e.Location);
                            }      
                        }
                        break;
                }
                switch (this.WorkState)
                {
                    case EnumWorkState.SelectedOne:
                        SelectedNodePos.DrawColorNodes(g, SelectedNodePos.pNode.Label, SelectedNodePos.cPoint, 0);
                        SelectedNodePos.DrawSelectedRectangle(g);
                        break;
                    case EnumWorkState.SelectedMultiple:
                        
                    default:
                        break;
                }
            }
            catch (Exception exp)
            {
                MessageBox.Show(exp.ToString());
            }
            //this.Refresh();
        }

        private void GraphGraphUserControl_MouseClick(object sender, MouseEventArgs e)
        {
            /*if (SelectedArcEdge != null)
            {
                this.gbuc.selectedEdgeToolStripStatusLabel_SetText("选中边为：" + SelectedArcEdge.pedge.ToString());
            }*/
            if (this.NewNodeTextBox.Visible && this.NewNodeTextBox.Focused)
            {
                try
                {
                    this.NewNodeTextBox_TextChanged(null, null);
                    if(this.Graph is GraphDatabase)
                        ((GraphDatabase)this.Graph).SaveNodePosision(NewNodePos.pNode, NewNodePos.cPoint);
                    this.NewNodeTextBox.Visible = false;
                    NewNodePos = null;
                }
                catch (Exception exp)
                {
                    MessageBox.Show(exp.ToString());
                }
            }
        }
        private void GraphGraphUserControl_DoubleClick(object sender, EventArgs e)
        {
            
            Node type = null;//关系节点
            //nodes = this.GraphDatabase.QueryNodes();
            if (SelectedLineEdge != null && SelectedNodePos == null)
            {
                type = SelectedLineEdge.pedge.FristLeaf.Class;
                try
                {
                    EditEdgeDialog dlg = new EditEdgeDialog((IGraphBase)this.Graph,
                        SelectedLineEdge.pedge.Outgoing, 
                        SelectedLineEdge.pedge.Incoming, 
                        type);
                    dlg.ShowDialog();
                    if (this.PositionView != null)
                        this.PositionView.LoadGraphView(GraphView);
                    else
                        this.PrepareLineAndArcGraph();
                    this.Refresh();
                }
                catch (Exception exp)
                {
                    MessageBox.Show(exp.ToString());
                }
            }
            if (SelectedArcEdge != null && SelectedNodePos == null)
            {
                type = SelectedArcEdge.pedge.FristLeaf.Class;
                try
                {
                    EditEdgeDialog dlg = new EditEdgeDialog((IGraphBase)this.Graph, 
                        SelectedLineEdge.pedge.Outgoing, 
                        SelectedArcEdge.pedge.Incoming, type);
                    dlg.ShowDialog();
                    //this.gbuc.Refresh_Controls(GraphDatabase.QueryNodes(),
                    //    GraphDatabase.QuerySingleEdge());
                    if (this.PositionView != null)
                        this.PositionView.LoadGraphView(GraphView);
                    else
                        this.PrepareLineAndArcGraph();
                    this.Refresh();
                }
                catch (Exception exp)
                {
                    MessageBox.Show(exp.ToString());
                }
            }
            //以上为对边进行编辑
            //下面是对节点进行打开
            if (SelectedNodePos != null)
            {
                this.SelNodeTextBox.Visible = false;
                this.NodeOpenEvent(this, SelectedNodePos.pNode);
            }
        }
        #endregion

        #region"鼠标右击事件"
        List<Node> newnodes = new List<Node>();
        NodePos NewNodePos;
        /// <summary>
        /// 新建节点
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void newNodeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                string label = "NewNode";
                Node newnode = base.Graph.AddNode(label);
                CreateNewNode(label, newnode);
            }
            catch (Exception exp)
            {
                MessageBox.Show(exp.ToString());
            }
        }
        /// <summary>
        /// 新建子图节点
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void toolStripMenuItemCreateSubGraph_Click(object sender, EventArgs e)
        {
            try
            {
                string label = "NewSubGraph";
                IGraph subgraph = null;
                if (((Node)this.Graph).NodeType == Node.EnumNodeType.SubGraph)
                {//本身是一个SubGraph，嵌套创建Grand SubGraph
                    subgraph = this.SuperGraph.CreateGrandSubGraph(this.Graph, label);
                }
                else
                {
                    subgraph = this.SuperGraph.CreateSubGraph(label);
                }
                CreateNewNode(label, (Node)subgraph);
            }
            catch (Exception exp)
            {
                MessageBox.Show(exp.ToString());
            }
        }

        void CreateNewNode(string label, Node NewNode)
        {
            //this.NewNodeTextBox.Text="";
            this.NewNodeTextBox.Location = PopupMenuPoint;
            if (canediting)
            {
                this.NewNodeTextBox.Visible = true;
                this.InProgram = true;
                this.NewNodeTextBox.Text = label;
                this.InProgram = false;
                this.NewNodePos = new NodePos(NewNode, this.PopupMenuPoint);
                GraphPositionManager.NodePositions.Add(NewNode.Id, NewNodePos);
                this.Refresh();
                //NewNodePos = null;
            }
        }

        private void ConnectNodeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Node node1=null;
            Node node2=null;
            ICollection<Node> nodes;
            
            if (this._selmultinodes.Count != 2)
            {
                MessageBox.Show("请重新选则两个节点！");
                this.Controls.Clear();
                this.Refresh();
            }
            else
            {
                if (this.Graph is Semantics.SubGraph)
                {
                    nodes = ((Semantics.SubGraph)this.Graph).SuperGraph.GetAllNodes();
                }
                else
                    nodes = this.Graph.GetAllNodes();
                foreach (Node node in nodes)
                {
                    if (node.Id == _selmultinodes.First<NodePos>().pNode.Id)
                    {
                        node1 = node;
                    }
                    if (node.Id == _selmultinodes.Last<NodePos>().pNode.Id)
                    {
                        node2 = node;
                    }
                }
                try
                {
                    EdgeDialog dlg = new EdgeDialog(this.Graph, (IList<Node>)nodes, node1, node2);
                    dlg.ShowDialog();
                    if (dlg.DialogResult != DialogResult.OK)
                        return;
                    IList<Edge> edges = this.Graph.GetAllEdges();//.QuerySingleEdge();
                    if (this.PositionView != null)
                        this.PositionView.LoadGraphView(GraphView);
                    else
                    {
                        this.LineEdges.Add(dlg.Edge);
                        this.PrepareLineAndArcGraph();
                    }
                    this.Refresh();
                    if (this.EdgeCreatedEvent != null)
                        this.EdgeCreatedEvent(this, dlg.Edge);
                }
                catch (Exception exp)
                {
                    MessageBox.Show(exp.ToString());
                }
            }
        }

        private void DeleteNodeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Edge deletearcedge ;
            


            if (this._selmultinodes.Count >= 2)
            {//删除多个节点
                List<Node> deletednodes = new List<Node>();
                foreach (NodePos np in _selmultinodes)
                {
                    try
                    {
                        this.Graph.RemoveNode(np.pNode);
                        deletednodes.Add(np.pNode);
                        this.GraphPositionManager.NodePositions.Remove(np.pNode.Id);

                        if (this.PositionView != null)
                            this.PositionView.LoadGraphView(GraphView);
                        else
                            this.PrepareLineAndArcGraph();
                        this.Refresh();
                        this.MultipleNodesDeletedEvent(this, deletednodes);
                        MessageBox.Show("删除成功！", "提示", MessageBoxButtons.OK);
                    }
                    catch (Exception exp)
                    {
                        MessageBox.Show(exp.ToString());
                    }
                }
            }
            if (this.SelectedNodePos != null)
            {
                Node deletenode = SelectedNodePos.pNode;
                try
                {
                    base.Graph.RemoveNode(deletenode);
                    this.GraphPositionManager.NodePositions.Remove(deletenode.Id);
                    this.NodeDeletedEvent(this, deletenode);
                    if (this.PositionView != null)
                        this.PositionView.LoadGraphView(GraphView);
                    else
                        this.PrepareLineAndArcGraph();
                    this.Refresh();
                    MessageBox.Show("删除成功！", "提示", MessageBoxButtons.OK);
                }
                catch (Exception exp)
                {
                    MessageBox.Show(exp.ToString());
                }
            }
            if (this.SelectedLineEdge != null )
            {
                Edge deletelineedge = SelectedLineEdge.pedge;
                try
                {
                    base.Graph.RemoveEdge(deletelineedge);
                    
                    if (this.PositionView != null)
                        this.PositionView.LoadGraphView(GraphView);
                    else
                        this.PrepareLineAndArcGraph();
                    this.EdgeDeletedEvent(this, deletelineedge);
                    MessageBox.Show("删除成功！", "提示", MessageBoxButtons.OK);
                }
                catch (Exception exp)
                {
                    MessageBox.Show(exp.ToString());
                }
            }
            if (this.SelectedArcEdge != null)
            {
                deletearcedge = SelectedArcEdge.pedge;
                try
                {
                    base.Graph.RemoveEdge(deletearcedge);
                    this.EdgeDeletedEvent(this, deletearcedge);
                    if (this.PositionView != null)
                        this.PositionView.LoadGraphView(GraphView);
                    else
                        this.PrepareLineAndArcGraph();
                    MessageBox.Show("删除成功！", "提示", MessageBoxButtons.OK);
                }
                catch (Exception exp)
                {
                    MessageBox.Show(exp.ToString());
                }
            }
        }

        void EditEdge(Edge edge)
        {
        }

        private void EditEdgeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Node node1 = null;//出节点
            Node node2 = null;//入节点
            Node type = null;//关系节点
            if (SelectedLineEdge != null) 
            {
                node1 = SelectedLineEdge.pedge.Outgoing;
                node2 = SelectedLineEdge.pedge.Incoming;
                type = SelectedLineEdge.pedge.FristLeaf.Class;
                try
                {
                    EditEdgeDialog dlg = new EditEdgeDialog((IGraphBase)this.Graph, SelectedLineEdge.pedge);
                    if (dlg.ShowDialog() != DialogResult.OK)
                        return;
                    this.EdgeEditedEvent(this, SelectedLineEdge.pedge);
                    if (this.PositionView != null)
                        this.PositionView.LoadGraphView(GraphView);
                    else
                        this.PrepareLineAndArcGraph();
                    this.Refresh();
                }
                catch (Exception exp)
                {
                    MessageBox.Show(exp.ToString());
                }
            }
            if (SelectedArcEdge != null)
            {
                node1 = SelectedArcEdge.pedge.Outgoing;
                node2 = SelectedArcEdge.pedge.Incoming;
                type = SelectedArcEdge.pedge.FristLeaf.Class;
                try
                {
                    EditEdgeDialog dlg = new EditEdgeDialog((IGraphBase)this.Graph, node1, node2, type);
                    dlg.ShowDialog();
                    this.EdgeEditedEvent(this, SelectedArcEdge.pedge);
                    if (this.PositionView != null)
                        this.PositionView.LoadGraphView(GraphView);
                    else
                        this.PrepareLineAndArcGraph();
                    this.Refresh();
                }
                catch (Exception exp)
                {
                    MessageBox.Show(exp.ToString());
                }
            }
        }

        public void ShowNodeNeighbor(Graph resultgraph, List<SortedList<int, Node>> neighborNodes)
        {
            this.GraphPositionManager.ShowNodeNeighbor(resultgraph, neighborNodes);
            this.Refresh();
        }

        //打开节点
        private void OpenNodeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                if (SelectedNodePos != null)
                {
                    this.NodeOpenEvent(this, SelectedNodePos.pNode);
                }
            }
            catch (Exception exp)
            {
                MessageBox.Show(this, exp.ToString());
            }
        }

        private void SearchNeighborToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //int count = GraphAdjacent.TopSortHops(SelectedNodePos.pNode);
        }
        #endregion      

        #region"显示视图"

        public void ShowGraphGraphView(Node viewnode)
        {
            this.GraphbaseViewType = viewnode;
            this.PositionView = new GraphPositionView(this.GraphPositionManager,this);
            this.PositionView.LoadGraphView(viewnode);
            this.GraphView = PositionView.GraphView;
        }

        #endregion


        /// <summary>
        ///
        /// </summary>
        internal void RefreshGraph()
        {
            IList<Node> nodes = this.Graph.GetAllNodes();
            this._nodes = new List<Node>();
            this._nodes.AddRange(nodes);

            IList<Edge> edges = this.Graph.GetAllEdges();
            this._edges = new List<Edge>();
            this._edges.AddRange(edges);
            
            this.PrepareDrawingGraph(nodes, edges);
            this.Refresh();
        }

        private void dismissNodeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (this.Graph is Semantics.SubGraph)
                ((Semantics.SubGraph)this.Graph).SuperGraph.DismissSubNode(this.Graph, this.SelectedNode);
            else
            {
                MessageBox.Show(this.Graph + "不是子图(SubGraph)!");
            }
        }
    }
}
